package com.itheima.tlias.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.tlias.dto.*;
import com.itheima.tlias.entity.Emp;
import com.itheima.tlias.entity.EmpExpr;
import com.itheima.tlias.entity.EmpLog;
import com.itheima.tlias.exception.BizException;
import com.itheima.tlias.mapper.EmpExprMapper;
import com.itheima.tlias.mapper.EmpMapper;
import com.itheima.tlias.service.EmpLogService;
import com.itheima.tlias.service.EmpService;
import com.itheima.tlias.utils.Constant;
import com.itheima.tlias.utils.JwtUtils;
import com.itheima.tlias.vo.EmpListVo;
import com.itheima.tlias.vo.EmpVo;
import com.itheima.tlias.vo.LoginVo;
import com.itheima.tlias.vo.PageBean;
import io.jsonwebtoken.Claims;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.*;

@Service
public class EmpServiceImpl implements EmpService {
    boolean result = true;
    @Autowired
    private EmpMapper empMapper;
    @Autowired
    private EmpExprMapper exprMapper;
    @Autowired
    private EmpLogService empLogService;

    @Override
    public PageBean<EmpListVo> empPage(EmpListDto empListDto) {
        //1. 设置分页参数
        // int page = (pageDto.getPage()-1)*pageDto.getPageSize();
        //框架开启分页
        PageHelper.startPage(empListDto.getPage(), empListDto.getPageSize());

        //2. 执行查询（框架返回Page对象）
        //List<EmpListVo> empListVos = empMapper.empPage(page, pageDto.getPageSize());
        Page<EmpListVo> empListVos = empMapper.empPage(empListDto);
        //3. 封装结果  getTotal总数    getResult
        return new PageBean<>(empListVos.getTotal(), empListVos.getResult());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addEmp(AddEmpDto addEmpDto) {
        if (empMapper.getByEmpUserName(addEmpDto.getUsername()) != null) {
            throw new BizException("用户名重复");
        }
        if (empMapper.getByEmpPhone(addEmpDto.getPhone()) != null) {
            throw new BizException("手机号重复");
        }

        try {
            Emp emp = new Emp();
            //复制属性
            BeanUtils.copyProperties(addEmpDto, emp);
            //补全基本信息
            emp.setPassword("123456");
            emp.setCreateTime(LocalDateTime.now());
            emp.setUpdateTime(LocalDateTime.now());
            ////保存基本信息
            empMapper.addEmp(emp);
            //工作经历

            // 前端传递的参数
            List<AddEmpExprDto> exprDtoList = addEmpDto.getExprList();
            // 只有 当有工作经历的时候才需要保存
            if (!CollectionUtils.isEmpty(exprDtoList)) {
                // 数据的实体对象
                List<EmpExpr> exprList = new ArrayList<>();
                for (AddEmpExprDto exprDto : exprDtoList) {
                    EmpExpr empExpr = new EmpExpr();
                    BeanUtils.copyProperties(exprDto, empExpr);
                    empExpr.setEmpId(emp.getId());
                    exprList.add(empExpr);
                }
                exprMapper.insertExprBatch(exprList);
            }
            result = true;
        } catch (Exception e) {
            result = false;
            throw new RuntimeException();
        } finally {
            //打印日志
            EmpLog empLog = new EmpLog();
            empLog.setOperateTime(LocalDateTime.now());
            empLog.setInfo("添加" + (result ? "成功" : "失败"));
            empLogService.insertLog(empLog);

        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByIds(List<Integer> ids) {
        empMapper.deleteByIds(ids);
        exprMapper.deleteByIds(ids);
    }

    @Override
    public EmpVo getById(Integer id) {
        EmpVo empVo = new EmpVo();
        EmpVo vo = empMapper.getById(id);
        List<EmpExpr> exprList = exprMapper.getByEmpId(id);
        BeanUtils.copyProperties(vo, empVo);
        empVo.setExprList(exprList);
        return empVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateEmp(UpdateEmpDto dto) {
        if (empMapper.getByEmpUserName(dto.getUsername()) != null &&
                !Objects.equals(empMapper.getByEmpUserName(dto.getUsername()).getId(), dto.getId())) {
            throw new BizException("用户名重复");
        }
        if (empMapper.getByEmpPhone(dto.getPhone()) != null &&
                !Objects.equals(empMapper.getByEmpPhone(dto.getPhone()).getId(), dto.getId())) {
            throw new BizException("手机号重复");
        }

        Emp emp = new Emp();
        BeanUtils.copyProperties(dto, emp);
        emp.setUpdateTime(LocalDateTime.now());
        empMapper.updateEmp(emp);
        exprMapper.deleteByIds(Arrays.asList(dto.getId()));
        List<EmpExpr> exprList = dto.getExprList();
        if (!CollectionUtils.isEmpty(exprList)) {
            for (EmpExpr empExpr : exprList) {
                empExpr.setEmpId(dto.getId());
            }
            exprMapper.insertExprBatch(exprList);
        }
    }

    @Override
    public List<Emp> empListByJob() {
        return empMapper.empListByJob();
    }


    //登录
    @Override
    public LoginVo login(LoginDto dto) {
        //1. 调用mapper方法查询数据库
        Emp e = empMapper.login(dto);

        //2. 判断
        if (e != null) { //登录成功 - 生成JWT令牌
            Map<String, Object> claims = new HashMap<>();
            claims.put("id", e.getId());
            claims.put("username", e.getUsername());
            claims.put("name", e.getName());
            //claims.put("password", e.getPassword());
            String jwt = JwtUtils.generateJwt(claims);
            return new LoginVo(e.getId(), e.getUsername(), e.getName(), jwt);
        } else throw new BizException("用户名或密码错误");
    }

    //修改密码
    @Override
    public void amendPassword(ChangePasswordDto dto, HttpServletRequest servletRequest) {
        String jwt = servletRequest.getHeader("token");
        Claims claims = JwtUtils.parseJWT(jwt);
        Integer id = claims.get(Constant.ID, Integer.class);
        String tokenPassword = claims.get(Constant.PASSWORD, String.class);
        if (tokenPassword.equals(dto.getPassword())) {
            empMapper.amendPassword(dto.getNewpassword(), id);
        } else {
            throw new BizException("密码错误，请重新输入");
        }
    }
}
